package em.program;

import base.jfinal.JsonUtil;
import base.util.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import em.job.ConnServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 终端与平台数据交互处理层
 */
public abstract class MsgApiHandle {
    private Log logger = LogFactory.getLog(MsgApiHandle.class);
    /**
     * 终端当前执行的命令
     */
    protected static Map<String,Integer> mapCurrentOrder=new ConcurrentHashMap<String,Integer>();

    /**
     * 解析出来的数据存储 默认1万个对列
     */
    private static BlockingQueue<String> arrDataStore=new ArrayBlockingQueue<String>(10000);

    /**
     * 读取线程
     */
    private static Thread threadRead,threadReadHandle;

    /**
     * 实时工况
     */
    protected abstract void realHandle(JSONObject json);

    /**
     * 其它数据处理
     */
    protected abstract void otherHandle(JSONObject json);

    public MsgApiHandle(){
        resetReadThread();
    }

    private void resetReadThread(){
        if(threadRead!=null && threadReadHandle!=null) return;
        //启动读取线程
        threadRead = new Thread(new Runnable() {
            @Override
            public void run() {
                read();
            }
        });
        threadRead.start();
        threadReadHandle=new Thread(new Runnable() {
            @Override
            public void run() {
                readHandle();
            }
        });
        threadReadHandle.start();
    }

    /**
     * 发送命令 用于发送指令
     * @param command
     */
    public boolean sendData(String command){
        return ConnServer.getInstance().sendData(command);
    }

    /**
     * 发送命令 主要是用于升级
     * @param command
     * @param bytes
     * @param start
     * @param end
     */
    public boolean sendData(String command, byte[] bytes,int start, int end){
        return ConnServer.getInstance().sendData(command,bytes,start,end);
    }

    /**
     * 读取数据流
     */
    private void read(){
        char[] charData=new char[10240];
        int iLen;
        try {
            while (true){
                Thread.sleep(2000);
                while (ConnServer.getInstance().isConn() && (iLen=ConnServer.getInstance().reader.read(charData)) != -1) {
                    arrDataStore.put(String.valueOf(charData,0,iLen));
                }
            }
        } catch (IOException e) {
            logger.error("读取数据流程时出现失败："+e.getMessage());
        }catch (InterruptedException e) {
            logger.error("读取数据时，数据已存储1万，已阻塞继续往存储数据队列里放数据："+e.getMessage());
        }
        read();
    }

    /**
     * 处理缓冲中的数据
     */
    private void readHandle(){
        //logger.debug("处理数据线程已启动");
        String strResult;
        JSONArray jsonArray=null;
        try {
            while (true){
                strResult = arrDataStore.take();
                if(StrKit.notBlank(strResult) && strResult.indexOf("{")!=-1 && strResult.indexOf("}")!=-1){
                    strResult= JsonUtil.verifyJson(strResult);
                    strResult=strResult.replace("}{","},{");
                    strResult="["+strResult+"]";
                    try {
                        jsonArray=JSONArray.parseArray(strResult);
                    }catch (Exception ex){
                        System.out.println("不是有效数据："+strResult+" 错误："+ex.getMessage());
                        continue;
                    }

                    for (int i = 0; i <jsonArray.size() ; i++) {
                        jsonArray.getJSONObject(i).put("currentTime", DateUtil.getInstance().getCurrentDate());//设置当前取得数据的时间
                        if (jsonArray.getJSONObject(i).getIntValue("ACTION")==9) {
                            realHandle(jsonArray.getJSONObject(i));
                        }else{
                            otherHandle(jsonArray.getJSONObject(i));
                        }
                    }
                }
            }
        } catch (InterruptedException e) {
            logger.error("处理缓冲中的数据失败："+e.getMessage());
        }
        readHandle();
    }
}
